package com.neusoft.neuiotms.dcom.service.impl;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import javax.persistence.EntityNotFoundException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.auth.common.bean.UserBean;
import com.neusoft.bizcore.file.service.FileService;
import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.neuiotms.dcom.converter.KnowledgeConverter;
import com.neusoft.neuiotms.dcom.dto.KnowledgeDTO;
import com.neusoft.neuiotms.dcom.model.Knowledge;
import com.neusoft.neuiotms.dcom.model.KnowledgeAttachment;
import com.neusoft.neuiotms.dcom.repository.KnowledgeAttachmentRepository;
import com.neusoft.neuiotms.dcom.repository.KnowledgeRepository;
import com.neusoft.neuiotms.dcom.service.KnowledgeService;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class KnowledgeServiceImpl implements KnowledgeService {

    @Autowired
    private KnowledgeRepository knowledgeRepository;

    @Autowired
    private KnowledgeConverter knowledgeConverter;

    @Autowired
    private FileService fileService;

    @Autowired
    private KnowledgeAttachmentRepository knowledgeAttachmentRepository;

    @Override
    public List<KnowledgeDTO> index(final Searchable searchable) {
        final List<Knowledge> model = this.knowledgeRepository.search(searchable);
        return this.knowledgeConverter.toListDTO(model);
    }

    @Override
    public Page<KnowledgeDTO> page(final Searchable searchable, final Pageable pageable) {
        final Page<Knowledge> page = this.knowledgeRepository.search(searchable, pageable);
        return this.knowledgeConverter.toPageDTO(page);
    }

    @Override
    public KnowledgeDTO create(final KnowledgeDTO dto, final UserBean user) {
        if (user != null) {
            dto.setUserCode(user.getUsername());
            dto.setUserName(user.getName());
        }
        final Knowledge model = this.knowledgeConverter.toModel(dto);
        this.knowledgeRepository.save(model);
        return this.knowledgeConverter.toDTO(model);
    }

    @Override
    public KnowledgeDTO update(final Long id, final KnowledgeDTO dto, final UserBean user) {
        Knowledge model;
        try {
            model = this.knowledgeRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            KnowledgeServiceImpl.log.error(e.getMessage(), e);
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }
        dto.setUpdateTime(new Date());
        if (user != null) {
            dto.setUpdateUserCode(user.getUsername());
            dto.setUpdateUserName(user.getName());
        }
        model = this.knowledgeConverter.toModel(dto);
        this.knowledgeRepository.save(model);
        return this.knowledgeConverter.toDTO(model);

    }

    @Override
    public KnowledgeDTO detail(final Long id) {
        Knowledge model;
        try {
            model = this.knowledgeRepository.getOne(id);
            return this.knowledgeConverter.toDTO(model);
        } catch (final EntityNotFoundException e) {
            KnowledgeServiceImpl.log.error(e.getMessage(), e);
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }
    }

    @Override
    public void delete(final Long id) {
        try {

            //删除MongoDB中的file文件
            final List<KnowledgeAttachment> list = this.knowledgeAttachmentRepository.findByKnowledgeId(id);
            if (!list.isEmpty()) {
                final List<String> fsIds = list.stream().map(KnowledgeAttachment::getFsId).collect(Collectors.toList());
                final List<KnowledgeAttachment> attachments = this.knowledgeAttachmentRepository.findByFsIdIn(fsIds);

                final Map<String, List<KnowledgeAttachment>> map =
                        attachments.stream().collect(Collectors.groupingBy(KnowledgeAttachment::getFsId));

                final Iterator<Entry<String, List<KnowledgeAttachment>>> it = map.entrySet().iterator();
                while (it.hasNext()) {
                    boolean flag = false;//判断是否有其他knowledge关联同一张图片
                    final Entry<String, List<KnowledgeAttachment>> entry = it.next();
                    for (final KnowledgeAttachment attach : entry.getValue()) {
                        if (attach.getKnowledge().getId().longValue() != id.longValue()) {
                            flag = true;
                            break;
                        }
                    }
                    if (!flag) {
                        this.fileService.deleteByFsId(entry.getKey());
                    }
                }

            }
            this.knowledgeRepository.deleteById(id);
        } catch (final EntityNotFoundException e) {
            KnowledgeServiceImpl.log.error(e.getMessage(), e);
            throw new UnitedException(e.getMessage(), new Object[] {id });
        }
    }

    @Override
    public void updateReadingVolume(final Long id) {
        Knowledge model;
        try {
            model = this.knowledgeRepository.findById(id).get();
            int volume = 0;
            if (model.getReadingVolume() != null) {
                volume = model.getReadingVolume().intValue();
            }
            model.setReadingVolume(++volume);
            this.knowledgeRepository.save(model);
        } catch (final EntityNotFoundException e) {
            KnowledgeServiceImpl.log.error(e.getMessage(), e);
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }
    }

    @Override
    //    @Transactional
    public void deleteMongoFile(final String fsId, final Long id) {
        final List<KnowledgeAttachment> list = this.knowledgeAttachmentRepository.findByFsId(fsId);
        boolean flag = false;//判断是否有其他knowledge关联同一张图片
        for (final KnowledgeAttachment attach : list) {
            if (attach.getKnowledge().getId().longValue() != id) {
                flag = true;
                break;
            }
        }
        if (!flag) {
            this.fileService.deleteByFsId(fsId);
        }
    }

}
